
import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

//该控件是通过 滑动拦截来做的  所以一些临界值计算似乎有点问题（也有可能是系统问题）   （待优化）
class ButtomSheet extends StatefulWidget {

  double minSheetHeight; //最小的展示大小
  double maxSheetHeight; // 对打的展示大小
  double maxDragDistance=0;//展示的部分的滑动距离
  double maxChildScrollDistance=0; // 子控件 最大的滑动距离
  double headHeight=0; // 头部高度
  Widget child;
  Widget head;
  bool isAnimated=false;
  Decoration? decoration;


  ButtomSheet({required this.child,required this.head,required this.minSheetHeight,required this.maxSheetHeight,required this.headHeight,this.maxChildScrollDistance=0,this.decoration}){
    if(minSheetHeight >maxSheetHeight){
      throw Exception("maxSheetHeight must be greater than minSheetHeight");
    }
    maxDragDistance=maxSheetHeight-minSheetHeight;
    maxChildScrollDistance=max(maxChildScrollDistance, maxDragDistance);
    // print("object  onPointerMove minSheetHeight=${minSheetHeight}  maxSheetHeight=${maxSheetHeight}  maxDragDistance${maxDragDistance}  maxChildScrollDistance=${maxChildScrollDistance}");
  }

  @override
  _ButtomSheetState createState() => _ButtomSheetState();
}

class _ButtomSheetState extends State<ButtomSheet> {

  Offset? lastMoveOffset;
  double moveDistance=0;
  double verticalDistance=0;
  bool ignoringChildScroll=true;
  ScrollController nestScrollController= ScrollController();

  @override
  void initState() {
    super.initState();
    nestScrollController.addListener(() {
      print("initState  ${nestScrollController.offset}");
    });
  }

  void changeController(bool isScroll){
    ignoringChildScroll=isScroll;
  }

  void moveEnd(){
    widget.isAnimated=true;
    if(verticalDistance>widget.maxDragDistance/2 ){
      if(moveDistance<=widget.maxDragDistance){
        verticalDistance=widget.maxDragDistance;
        moveDistance=widget.maxDragDistance;
      }
    }else{
      verticalDistance=0;
      moveDistance=0;
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.bottomCenter,
      child: Listener(
        onPointerDown: (PointerDownEvent event){
          widget.isAnimated=false;
          lastMoveOffset=event.position;
        },
        onPointerMove: (PointerMoveEvent event){
          widget.isAnimated=false;
          if(lastMoveOffset !=null){
            double distance=lastMoveOffset!.dy-event.position.dy;
            if((moveDistance+distance)>widget.maxChildScrollDistance){//如果移动距离超过  最大滑动距离
              lastMoveOffset=Offset(event.position.dx, lastMoveOffset!.dy-(widget.maxChildScrollDistance-moveDistance));
              moveDistance=widget.maxChildScrollDistance;
            }else if((moveDistance+distance)<=0){//如果移动距离小于 0
              lastMoveOffset=Offset(event.position.dx, lastMoveOffset!.dy+moveDistance);
              moveDistance=0;
            }else{
              moveDistance+=distance;
              lastMoveOffset=event.position;
            }
            // print("object  onPointerMove _ovHeight=${widget.maxChildScrollDistance}  moveDistance=${moveDistance}  widget.maxDragDistance${widget.maxDragDistance}  distance=${distance}");
            if(moveDistance>widget.maxDragDistance){
              verticalDistance=widget.maxDragDistance;
              changeController(false);
            }else{
              verticalDistance=moveDistance;
              changeController(true);
            }
            setState(() {
            });
          }
        },
        onPointerUp:(PointerUpEvent event){
          moveEnd();
        },
        onPointerCancel:(PointerCancelEvent event){
          moveEnd();
        },
        child: AnimatedContainer(
          decoration: widget.decoration,
          duration: Duration(milliseconds: widget.isAnimated?500:0),
          alignment: Alignment.topCenter,
          height: widget.minSheetHeight+verticalDistance,
          child:OverflowBox(
            alignment:Alignment.topCenter,
            child: IgnorePointer(
              ignoring: ignoringChildScroll,
              child: NestedScrollView(
                headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
                   return [
                     SliverPersistentHeader(delegate: ChildSliverPersistentHeaderDelegate(
                       child: widget.head,maxHeight: widget.headHeight,minHeight: widget.headHeight
                     ),pinned: true,floating: true,),
                   ];
                },
                body: widget.child,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class ChildSliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate{

  double maxHeight;
  double minHeight;
  Widget child;

  ChildSliverPersistentHeaderDelegate({required this.maxHeight,required this.minHeight,required this.child});

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
     return child;
  }

  @override
  double get maxExtent => maxHeight;

  @override
  double get minExtent => minHeight;

  @override
  bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }

}